#include "marketwindow.h"
#include "ui_marketwindow.h"
#include <QtCharts>
#include <QMessageBox>
#include <cmath>
#include "analysiswindow.h"

// using namespace QtCharts;

//戴&苏代码
MarketWindow::MarketWindow(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MarketWindow)
{
    ui->setupUi(this);
    
    // 初始化图表
    chart = new QChart();
    chart->setTitle("电力价格交易曲线");
    
    // 初始化曲线系列
    supplierSeries = new QLineSeries();
    supplierSeries->setName("供电端价格曲线");
    supplierSeries->setPen(QPen(Qt::blue, 2));
    
    consumerSeries = new QLineSeries();
    consumerSeries->setName("用户端价格曲线");
    consumerSeries->setPen(QPen(Qt::red, 2));
    
    intersectionSeries = new QScatterSeries();
    intersectionSeries->setName("交点");
    intersectionSeries->setMarkerSize(10);
    intersectionSeries->setColor(Qt::green);
    
    // 添加系列到图表
    chart->addSeries(supplierSeries);
    chart->addSeries(consumerSeries);
    chart->addSeries(intersectionSeries);
    
    // 创建坐标轴
    axisX = new QValueAxis();
    axisX->setTitleText("电量");
    axisX->setRange(0, 100);  // 初始范围，会根据数据调整
    
    axisY = new QValueAxis();
    axisY->setTitleText("电价");
    axisY->setRange(0, 100);  // 初始范围，会根据数据调整
    
    // 设置坐标轴
    chart->setAxisX(axisX, supplierSeries);
    chart->setAxisY(axisY, supplierSeries);
    chart->setAxisX(axisX, consumerSeries);
    chart->setAxisY(axisY, consumerSeries);
    chart->setAxisX(axisX, intersectionSeries);
    chart->setAxisY(axisY, intersectionSeries);
    
    // 添加图表到视图
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);
}

MarketWindow::~MarketWindow()
{
    delete ui;
    delete chart;
    delete supplierSeries;
    delete consumerSeries;
    delete intersectionSeries;
    delete axisX;
    delete axisY;
}

void MarketWindow::setBidData(const QVector<PriceQuantity> &supplierData, 
                            const QVector<PriceQuantity> &consumerData)
{
    // 清空之前的数据
    supplierSeries->clear();
    consumerSeries->clear();
    intersectionSeries->clear();
    
    // 生成供电端阶梯曲线数据（递增）
    double currentQuantity = 0;
    for (const auto &item : supplierData) {
        // 当前阶梯的结束电量
        double endQuantity = currentQuantity + item.quantity;
        
        // 添加阶梯线段（水平线）
        supplierSeries->append(currentQuantity, item.price);
        supplierSeries->append(endQuantity, item.price);
        
        currentQuantity = endQuantity;
    }
    
    // 生成用户端阶梯曲线数据（递减）
    currentQuantity = 0;
    for (const auto &item : consumerData) {
        // 当前阶梯的结束电量
        double endQuantity = currentQuantity + item.quantity;
        
        // 添加阶梯线段（水平线）
        consumerSeries->append(currentQuantity, item.price);
        consumerSeries->append(endQuantity, item.price);
        
        currentQuantity = endQuantity;
    }
    
    // 计算交点
    calculateIntersection();
    
    // 调整坐标轴范围以适应数据
    auto allPoints = supplierSeries->points() + consumerSeries->points();
    if (!allPoints.isEmpty()) {
        double minX = allPoints[0].x(), maxX = allPoints[0].x();
        double minY = allPoints[0].y(), maxY = allPoints[0].y();
        
        for (const auto &point : allPoints) {
            minX = qMin(minX, point.x());
            maxX = qMax(maxX, point.x());
            minY = qMin(minY, point.y());
            maxY = qMax(maxY, point.y());
        }
        
        // 留出一些边距
        axisX->setRange(minX - 5, maxX + 5);
        axisY->setRange(minY - 5, maxY + 5);
    }
}

double calculateStaircaseIntegral(const QList<QPointF>& points, double maxX) {
    double integral = 0.0;

    for (int i = 0; i < points.size() - 1; ++i) {
        QPointF p1
            = points[i];
        QPointF p2
            = points[i + 1];

        // 只处理水平线段
        if (!qFuzzyCompare(p1.y(), p2.y())) continue;

        // 计算当前线段在交点前的有效长度
        double segmentStart = p1.x();
        double segmentEnd = p2.x();

        // 如果线段完全在交点左侧
        if (segmentEnd <= maxX) {
            integral
                += (segmentEnd - segmentStart) * p1.y();
        }
        // 如果线段部分在交点左侧
        else if (segmentStart < maxX) {
            integral
                += (maxX - segmentStart) * p1.y();
            break;  // 后续线段都在交点右侧，无需计算
        }
        // 如果线段完全在交点右侧，结束计算
        else {
            break;
        }
    }

    return integral;
}



void MarketWindow::calculateIntersection()
{
    // 获取曲线数据点
    QList<QPointF> supplierPoints = supplierSeries->points();
    QList<QPointF> consumerPoints = consumerSeries->points();

    // 查找交点
    for (int i = 0; i < supplierPoints.size() - 1; ++i) {
        // 供电端线段
        QPointF s1 = supplierPoints[i];
        QPointF s2 = supplierPoints[i + 1];

        // 判断供电端线段类型
        bool sIsHorizontal = qFuzzyCompare(s1.y(), s2.y());
        bool sIsVertical = qFuzzyCompare(s1.x(), s2.x());

        // 只处理水平或垂直线段
        if (!sIsHorizontal && !sIsVertical) continue;

        for (int j = 0; j < consumerPoints.size() - 1; ++j) {
            // 用户端线段
            QPointF c1 = consumerPoints[j];
            QPointF c2 = consumerPoints[j + 1];

            // 判断用户端线段类型
            bool cIsHorizontal = qFuzzyCompare(c1.y(), c2.y());
            bool cIsVertical = qFuzzyCompare(c1.x(), c2.x());

            // 只处理水平或垂直线段
            if (!cIsHorizontal && !cIsVertical) continue;

            QPointF intersection;
            bool found = false;

            // 情况1：横线与横线相交（原有逻辑）
            if (sIsHorizontal && cIsHorizontal) {
                // 检查y值是否相等（价格相同）
                if (qFuzzyCompare(s1.y(), c1.y())) {
                    // 检查x范围是否重叠（电量范围有交集）
                    double sMinX = qMin(s1.x(), s2.x());
                    double sMaxX = qMax(s1.x(), s2.x());
                    double cMinX = qMin(c1.x(), c2.x());
                    double cMaxX = qMax(c1.x(), c2.x());

                    double overlapMin = qMax(sMinX, cMinX);
                    double overlapMax = qMin(sMaxX, cMaxX);

                    if (overlapMin <= overlapMax) {
                        // 取重叠区域的中点作为交点
                        intersection.setX((overlapMin + overlapMax) / 2);
                        intersection.setY(s1.y());
                        found = true;
                    }
                }
            }
            // 情况2：竖线与竖线相交
            else if (sIsVertical && cIsVertical) {
                // 检查x值是否相等
                if (qFuzzyCompare(s1.x(), c1.x())) {
                    // 检查y范围是否重叠
                    double sMinY = qMin(s1.y(), s2.y());
                    double sMaxY = qMax(s1.y(), s2.y());
                    double cMinY = qMin(c1.y(), c2.y());
                    double cMaxY = qMax(c1.y(), c2.y());

                    double overlapMinY = qMax(sMinY, cMinY);
                    double overlapMaxY = qMin(sMaxY, cMaxY);

                    if (overlapMinY <= overlapMaxY) {
                        // 取重叠区域的中点作为交点
                        intersection.setX(s1.x());
                        intersection.setY((overlapMinY + overlapMaxY) / 2);
                        found = true;
                    }
                }
            }
            // 情况3：横线与竖线相交
            else if (sIsHorizontal && cIsVertical) {
                // 供电端是横线，用户端是竖线
                double hY = s1.y();  // 横线y值
                double vX = c1.x();  // 竖线x值

                // 检查x是否在横线范围内
                double hMinX = qMin(s1.x(), s2.x());
                double hMaxX = qMax(s1.x(), s2.x());
                bool xInRange = (vX >= hMinX && vX <= hMaxX);

                // 检查y是否在竖线范围内
                double vMinY = qMin(c1.y(), c2.y());
                double vMaxY = qMax(c1.y(), c2.y());
                bool yInRange = (hY >= vMinY && hY <= vMaxY);

                if (xInRange && yInRange) {
                    intersection.setX(vX);
                    intersection.setY(hY);
                    found = true;
                }
            }
            // 情况4：竖线与横线相交
            else if (sIsVertical && cIsHorizontal) {
                // 供电端是竖线，用户端是横线
                double vX = s1.x();  // 竖线x值
                double hY = c1.y();  // 横线y值

                // 检查x是否在横线范围内
                double hMinX = qMin(c1.x(), c2.x());
                double hMaxX = qMax(c1.x(), c2.x());
                bool xInRange = (vX >= hMinX && vX <= hMaxX);

                // 检查y是否在竖线范围内
                double vMinY = qMin(s1.y(), s2.y());
                double vMaxY = qMax(s1.y(), s2.y());
                bool yInRange = (hY >= vMinY && hY <= vMaxY);

                if (xInRange && yInRange) {
                    intersection.setX(vX);
                    intersection.setY(hY);
                    found = true;
                }
            }

            // 如果找到交点
            if (found) {
                intersectionPoint = intersection;
                intersectionSeries->append(intersectionPoint);


                // 计算交点前的积分
                supplierIntegral
                    = calculateStaircaseIntegral(supplierPoints, intersectionPoint.x());
                consumerIntegral
                    = calculateStaircaseIntegral(consumerPoints, intersectionPoint.x());


                // 添加交点标签
                QChart *chart = supplierSeries->chart();
                QGraphicsTextItem *label = chart->scene()->addText(QString("交点: (%1, %2)").arg(intersection.x(), 0, 'f', 2).arg(intersection.y(), 0, 'f', 2));
                label->setPos(intersection.x(), intersection.y());
                label->setDefaultTextColor(Qt::darkGreen);


                QString labelText = QString("\n供电积分: %1\n用户积分: %2")
                                        .arg(supplierIntegral, 0, 'f', 2)
                                        .arg(consumerIntegral, 0, 'f', 2);
                QGraphicsTextItem *label2 = chart->scene()->addText(labelText);

                // 新增：用户积分减供电积分标签
                double integralDiff = consumerIntegral - supplierIntegral;
                QGraphicsTextItem *diffLabel = chart->scene()->addText(
                    QString("社会福祉: %1").arg(integralDiff, 0, 'f', 2)
                    );
                diffLabel->setPos(label2->x(), label2->y() + label2->boundingRect().height());
                diffLabel->setDefaultTextColor(Qt::darkGreen);


                // 发送信号通知交点已找到
                emit intersectionFound(intersectionPoint);
                return;
            }
        }
    }

    // 如果没有找到交点（保持原有逻辑）
    intersectionPoint = QPointF(-1, -1);
    // 可以在这里添加未找到交点的处理逻辑，如弹出提示
}
